SCA 是由幾家國(guó)內(nèi)外知名企業(yè)聯(lián)合制定的,他們成立了一個(gè)名為OSOA的組織,SCA
標(biāo)準(zhǔn)目前還在完善階段,它于
2005
年
11
月發(fā)布了
0.9
版本,目前版本已經(jīng)到了
0.96
。在
0.9
版本中,
SCA
標(biāo)準(zhǔn)就提出了
Java
實(shí)現(xiàn)以及
C++
實(shí)現(xiàn)標(biāo)準(zhǔn),而且在以后的版本中,會(huì)陸續(xù)加入其他的實(shí)現(xiàn)標(biāo)準(zhǔn),也就是說(shuō)
SCA
并不是只針對(duì)某一種語(yǔ)言的,不同語(yǔ)言或者環(huán)境之間通過(guò)開放的,標(biāo)準(zhǔn)的技術(shù)來(lái)實(shí)現(xiàn)互操作,比如我們常見(jiàn)的WebService等
。
SCA
提出的這套基于
SOA
去構(gòu)建企業(yè)應(yīng)用的編程模型,它的基礎(chǔ)思想就將業(yè)務(wù)功能構(gòu)造成一系列的服務(wù),并且能夠很好地將這些服務(wù)組合起來(lái),達(dá)到解決業(yè)務(wù)需求的目的。在構(gòu)建這些應(yīng)用時(shí)所用到的服務(wù),不僅包含新建服務(wù),而且可以包括已有的業(yè)務(wù)應(yīng)用中的業(yè)務(wù)功能,也就是說(shuō),
SCA
提供了一套針對(duì)服務(wù)組合和服務(wù)創(chuàng)建的模型。
目前來(lái)看,雖然有很多標(biāo)榜自己是基于
SOA
的產(chǎn)品或者框架,但是大部分還是各自為戰(zhàn),而
SCA
的出現(xiàn)有望統(tǒng)一基于
SOA
思想的框架。
Apache
已經(jīng)在最近完成了
SCA
標(biāo)準(zhǔn)的實(shí)現(xiàn),各位可以去
Apache
的網(wǎng)站看看。國(guó)內(nèi)的一家
Framework
廠商普元也加入到了
OSOA
,并且也宣布會(huì)在
2007
年發(fā)布一套
SCA
框架的
Framework
。
?
SCA
具體的應(yīng)用目前還不太清楚,不過(guò)
IBM
的新版本
Websphere
實(shí)現(xiàn)了
SCA 0.9
標(biāo)準(zhǔn),估計(jì)慢慢地會(huì)讓
SCA
得到更廣泛的應(yīng)用。在這片文章里我想簡(jiǎn)單談?wù)?/span>
SCA
中的一些重要概念:
Module,Component,ComponentType,Entry Point,External Service
。
?
Module
Module
是
SCA
構(gòu)架中重要的組成單元,也是粒度較粗的一個(gè)單元。
Module
在
SCA 0.9
以后版本改成了
Composite
,這可能是
OSOA
組織為了更加明確化其含義而進(jìn)行的一些命名更改。在
SCA 0.96
版本中,
Module
具有了屬性,這是為了能夠更加方便地注入給
Component
屬性值而做的調(diào)整。總之在
SCA 0.9
以及后續(xù)版本中做了一些改進(jìn),但是大體的框架沒(méi)有發(fā)生變化,如圖所表示:
它包括了
Component,Entry Point,External Service
,
Wire
等元素,而這些元素互相之間有一定的關(guān)聯(lián),上圖中沒(méi)有畫出
Wire
,因?yàn)?/span>
Wire
是專門針對(duì)
Service Reference
連接
Component
以及
Entry Point
連接到
Component
的描述,在上圖中我已經(jīng)畫出了這幾種元素之間的關(guān)系和連接,所以也就沒(méi)有必要專門指出
Wire
,如果需要獲得更多詳細(xì)的信息,可以去
DW
或者
Dev2Dev
查看
SCA
規(guī)范。
描述
Module
是通過(guò)一個(gè)
XML
格式文件進(jìn)行描述的,下面是該
XML
文件的一個(gè)大體格式:
<?
xml?version="1.0"?encoding="ASCII"
?>
<
module?
xmlns
=”http://www.osoa.org/xmlns/sca/0.9”
xmlns:v
="http://www.osoa.org/xmlns/sca/values/0.9"
name
="xs:NCName"
?
>
<
entryPoint?
name
="xs:NCName"
?multiplicity
="0..1?or?1..1?or?0..n?or?1..n"
?
>
*
<
interface
.interface-type
/>
<
binding
.binding-type?uri
="xs:anyURI"
/>
+
<
reference
>
wire-target-URI
</
reference
>
</
entryPoint
>
<
component?
name
="xs:NCName"
>
*
<
implementation
.implementation-type
/>
<
properties
>
?
<
v:property-name
>
property-value
</
v:property-name
>
+
</
properties
>
<
references
>
?
<
v:reference-name
>
wire-target-URI
</
v:reference-name
>
+
</
references
>
</
component
>
<
externalService?
name
="xs:NCName"
>
*
<
interface
.interface-type
/>
+
<
binding
.binding-type?uri
="xs:anyURI"
/>
*
</
externalService
>
<
wire
>
*
<
source
.uri
>
wire-source-URI
</
source.uri
>
<
target
.uri
>
wire-target-URI
</
target.uri
>
</
wire
>
</
module
>
?
ComponentType
和
Component
對(duì)于一個(gè)
Module
內(nèi)部來(lái)說(shuō),
Component
是絕對(duì)的主力。
要說(shuō)起
Component
,
ComponentType
就不得不說(shuō)。
ComponentType
是一個(gè)描述
SCA
中服務(wù)的元素,它定義了服務(wù)以及服務(wù)的接口,以及服務(wù)對(duì)應(yīng)的屬性和服務(wù)引用。
ComponentType
是通過(guò)一個(gè)后綴名為
.componentType XML
文檔來(lái)描述的,描述如下:
<
componentType?
xmlns
="http://www.osoa.org/xmlns/sca/0.9"
>
<
service?
name
="MyValueService"
>
<
interface
.java?interface
="services.myvalue.MyValueService"
/>
</
service
>
<
reference?
name
="customerService"
>
<
interface
.java?interface
="services.customer.CustomerService"
/>
</
reference
>
<
reference?
name
="stockQuoteService"
>
<
interface
.java?interface
="services.stockquote.StockQuoteService"
/>
</
reference
>
<
property?
name
="currency"
?type
="xsd:string"
?default
="USD"
/>
</
componentType
>
?
服務(wù)的接口目前分為兩種:
Java interface
和
WSDL
,這很好理解,
Java interface
就不說(shuō)了,
WSDL
想必大家也都知道,通過(guò)它的描述我們可以得到一個(gè)很準(zhǔn)確的接口。服務(wù)接口是一個(gè)可以擴(kuò)展的屬性,我們可以定義出其他不同的接口類型,當(dāng)然,前提是所使用的
SCA
必須能識(shí)別并支持才行。
服務(wù)的屬性和服務(wù)引用和
Spring
的屬性以及引用類似。
ComponentType
描述的這些屬性和引用,在
SCA Runtime
中實(shí)例化服務(wù)時(shí),是需要注入的。屬性一般對(duì)應(yīng)的是一些簡(jiǎn)單類型,復(fù)雜類型只能是
SDO
和
JAXB
;而引用則是需要對(duì)應(yīng)的也是一個(gè)服務(wù),在實(shí)例服務(wù)的時(shí)候,服務(wù)所引用的其他服務(wù)也需要一起實(shí)例化并注入。(注入的前提是該屬性或者引用的
requied
屬性為
true
,否則
SCA
就不會(huì)注入)。
ComponentType
只是描述性地說(shuō)明一下服務(wù)的的接口以及屬性,引用,但是具體該服務(wù)對(duì)應(yīng)的實(shí)現(xiàn)以及屬性的值和引用對(duì)應(yīng)的服務(wù)是沒(méi)有給出的。
Component
就是完成上述
ComponentType
沒(méi)有完成的工作。
我們可以把
ComponentType
想象成一個(gè)
Class
,而
Component
是這個(gè)
Class
的一個(gè)
Instance
。
Component
描述了服務(wù)對(duì)應(yīng)的實(shí)現(xiàn),服務(wù)實(shí)現(xiàn)是通過(guò)
implement
元素指定的。這里要注意,
SCA
中,實(shí)現(xiàn)是一個(gè)比較廣的概念,不僅僅是一個(gè)簡(jiǎn)單的
Java
類實(shí)現(xiàn),
Component
所對(duì)應(yīng)的實(shí)現(xiàn)和
ComponentType
中所定義的接口一樣,是有不同類型的。目前來(lái)看,
SCA
規(guī)范中給
implement
元素定義了只給出了一個(gè)
Java
實(shí)現(xiàn):
JavaImplement
,在
SCA
的一些其他擴(kuò)展信息中,提出了
BEPL
實(shí)現(xiàn)以及
EJB
實(shí)現(xiàn)等。
同樣,
Component
也描述了
ComponentType
中定義的屬性以及引用所對(duì)應(yīng)的值。
Component
的
XML
描述是在
Module
的描述文件中的,下面給出一個(gè)片段:
<
component?
name
="xs:NCName"
>
*
<
implementation
.implementation-type
/>
<
properties
>
?
<
v:property-name?
override
="no?or?may?or?must"
?
modulePropertyName
="xs:NCName"
?
>
property-value
</
v:property-name
>
+
</
properties
>
<
references
>
?
<
v:reference-name
>
wire-target-URI
</
v:reference-name
>
+
</
references
>
</
component
>
?
對(duì)于我們剛才提到的服務(wù)引用,這里我想羅嗦幾句。
服務(wù)引用并不是一個(gè)調(diào)用順序或者調(diào)用關(guān)系的描述,它只是指出了服務(wù)之間的引用關(guān)系,并且能夠動(dòng)態(tài)注入而已。很多人認(rèn)為,
SOA
中服務(wù)和服務(wù)之間是可以通過(guò)業(yè)務(wù)規(guī)則連接起來(lái),然后可以逐個(gè)調(diào)用,像一個(gè)
Flow
一樣,其實(shí)不然,
SOA
更重要的是關(guān)注服務(wù),比如
SCA
就很重視對(duì)服務(wù)的管理,以及將服務(wù)接口和實(shí)現(xiàn)解偶,服務(wù)和服務(wù)之間的連接也只是引用而已,并不是調(diào)用順序。用過(guò)
Seebeyond
(比較早的一個(gè)面向服務(wù)的框架,已經(jīng)被
SUN
收購(gòu))的人都知道,真正去啟動(dòng)服務(wù)編排調(diào)用的還是
BEPL
。同樣
SCA
中之所以提出了
Component
的
BEPL
實(shí)現(xiàn),也是出于對(duì)服務(wù)編排調(diào)用的考慮。
?
EntryPoint
Module
在
SCA
中是一個(gè)粒度較為粗的單元,
Module
和
Module
之間的交互是通過(guò)定義在
Module
內(nèi)部的
Entry Point
和
External Service
進(jìn)行的,也就是說(shuō)
Entry Point
是一個(gè)
Module
對(duì)外提供的接口,而
External Service
是一個(gè)
Module
對(duì)外訪問(wèn)的出口。
?
?
Entry Point
自身是只能定義自己的訪問(wèn)接口,但是真正的具體實(shí)現(xiàn)(比如一個(gè)
Java Class
),是通過(guò)它自身的
Reference
指定的。
Reference
指向的是一個(gè)
Component
,這就意味著,該
Entry Point
的調(diào)用是直接利用
Component
的實(shí)現(xiàn)來(lái)完成的。下面是
EntryPoint
的描述片段:
<
entryPoint?
name
="MyValueService"
>
<
interface
.java?interface
="services.myvalue.MyValueService"
/>
<
binding
.ws?port
="http://www.myvalue.org/MyValueService#
wsdl.endpoint(MyValueService/MyValueServiceSOAP)"
/>
<
reference
>
MyValueServiceComponent
</
reference
>
</
entryPoint
>
?
而一個(gè)
Entry Point
既然是對(duì)外的接口,那么它就不能像我們?cè)L問(wèn)一個(gè)普通
Java
類那么去訪問(wèn)了,所以在對(duì)外發(fā)布
Entry Point
是需要通過(guò)其他的一些輔助技術(shù)來(lái)完成,比如
Web Service
,
JMS
等,問(wèn)題在于如何確定該
Entry Point
所對(duì)應(yīng)的這些輔助技術(shù)(應(yīng)該說(shuō)是某種協(xié)議)呢?
SCA
規(guī)定,一個(gè)
Entry Point
需要指出它的
Binding
,利用
Binding
來(lái)確定該
Entry Point
具體是需要通過(guò)什么協(xié)議來(lái)進(jìn)行發(fā)布的。
?
Binding
Binding
是一個(gè)可以擴(kuò)展的元素,目前
SCA 0.9
中給出了兩種
Binding: SCA, Web Service
,不過(guò)我們是可以對(duì)
Binding
進(jìn)行擴(kuò)展的,前提是所使用的
SCA
容器必須支持?jǐn)U展的
Binding
。
一旦
Entry Point
指明了自己的
Binding
后,
SCA
容器就應(yīng)該根據(jù)它所指定的
Binding
類型對(duì)它進(jìn)行對(duì)外發(fā)布。比如
Entry Point A
指定了一個(gè)
Web Service Binding
,那
SCA
就必須能將這個(gè)服務(wù)通過(guò)
Web Service
的實(shí)行發(fā)布出去(不要聯(lián)想到
UDDI
,這里的發(fā)布只是說(shuō)將這個(gè)
Entry Point
制作成一個(gè)
Web Service
,能讓外界通過(guò)
Web Service
的訪問(wèn)方式訪問(wèn)到該
Entry Point
)。具體
SCA
如何實(shí)現(xiàn)我們不得而知。
?
廣告
本人的一個(gè)簡(jiǎn)單的
SCA Container
實(shí)現(xiàn),可以在uxbalto.googlepages.com得到
相關(guān)信息,不過(guò)頁(yè)面沒(méi)怎么加,東西少得可憐。
?
External Service
既然理解了
Binding
,那理解
External Service
就容易許多了。先看看描述片段:
<
externalService?
name
="CustomerService"
>
<
interface
.java?interface
="services.customer.CustomerService"
/>
<
binding
.sca
/>
</
externalService
>
<
externalService?
name
="StockQuoteService"
>
<
interface
.java?interface
="services.stockquote.StockQuoteService"
/>
<
binding
.ws?port
="http://www.stockquote.org/StockQuoteService#
wsdl.endpoint(StockQuoteService/StockQuoteServiceSOAP)"
/>
</
externalService
>
?
External Service
和
Entry Point
類似,只是一個(gè)是對(duì)外發(fā)布,一個(gè)是要去遠(yuǎn)程訪問(wèn)而已。我們一旦指明了
External Service
的
Binding
后,在訪問(wèn)該
External Service
提供的服務(wù)時(shí),我們就會(huì)通過(guò)指定
Binding
類型對(duì)遠(yuǎn)程發(fā)布的服務(wù)進(jìn)行訪問(wèn)。
其實(shí)不難看出,由于
SCA
中
Module
和
Module
之間的交互需要通過(guò)這么一種遠(yuǎn)程發(fā)布和訪問(wèn)的方式,可以認(rèn)為
Entry Point
和
External Service
之間是被調(diào)用和調(diào)用的關(guān)系,
Entry Point
發(fā)布出去的服務(wù),一般都是由
External Service
訪問(wèn)的。當(dāng)然,
External Service
不一定非要去訪問(wèn)
SCA
容器中的東西,單獨(dú)的非
SCA
管理的
Web Service
或者其他什么也可以利用
External Service
去訪問(wèn)的。
?
結(jié)束語(yǔ)
SCA
規(guī)范中還有很多沒(méi)有在文中提起,比如異步調(diào)用,服務(wù)的
Scope,SubSystem
等,我會(huì)在以后的文章中再和大家一起討論。